﻿#pragma once

#include "../MirEnvir/Envir.h"
#include "../MessageQueue.h"
#include "NPCInfo.h"
#include "../MirObjects/NPCObject.h"
#include "../../Shared/Enums.h"
#include "../../Shared/Data/SharedData.h"
#include "../MirObjects/PlayerObject.h"
#include "../../Shared/Data/ClientData.h"
#include "MonsterInfo.h"
#include "../../Shared/Data/ItemData.h"
#include <string>
#include <vector>
#include <algorithm>
#include <limits>
#include "../../stringhelper.h"
#include "../../tangible_filesystem.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace Server::MirDatabase { class QuestItemTask; }
namespace Server::MirDatabase { class QuestKillTask; }
namespace Server::MirDatabase { class QuestFlagTask; }

using namespace Server::MirObjects;
using namespace Server::MirEnvir;

namespace Server::MirDatabase
{
    class QuestInfo
    {
    public:
        virtual ~QuestInfo()
        {
            delete NpcInfo;
            delete _regexMessage;
        }

    protected:
        static Server::MirEnvir::Envir *getEnvir();

        static Server::MirEnvir::Envir *getEditEnvir();

        static Server::MessageQueue *getMessageQueue();

    public:
        int Index = 0;

        unsigned int NpcIndex = 0;
        NPCInfo *NpcInfo;

    private:
        unsigned int _finishNpcIndex = 0;

    public:
        unsigned int getFinishNpcIndex() const;
        void setFinishNpcIndex(unsigned int value);

        NPCObject *getFinishNPC() const;

        std::string Name = std::string::Empty, Group = std::string::Empty, FileName = std::string::Empty, GotoMessage = std::string::Empty, KillMessage = std::string::Empty, ItemMessage = std::string::Empty, FlagMessage = std::string::Empty;

        std::vector<std::string> Description = std::vector<std::string>();
        std::vector<std::string> TaskDescription = std::vector<std::string>();
        std::vector<std::string> CompletionDescription = std::vector<std::string>();

        int RequiredMinLevel = 0, RequiredMaxLevel = 0, RequiredQuest = 0;
        RequiredClass RequiredClass = RequiredClass::None;

        QuestType Type = static_cast<QuestType>(0);

        std::vector<QuestItemTask*> CarryItems = std::vector<QuestItemTask*>();

        std::vector<QuestKillTask*> KillTasks = std::vector<QuestKillTask*>();
        std::vector<QuestItemTask*> ItemTasks = std::vector<QuestItemTask*>();
        std::vector<QuestFlagTask*> FlagTasks = std::vector<QuestFlagTask*>();

        unsigned int GoldReward = 0;
        unsigned int ExpReward = 0;
        unsigned int CreditReward = 0;
        std::vector<QuestItemReward*> FixedRewards = std::vector<QuestItemReward*>();
        std::vector<QuestItemReward*> SelectRewards = std::vector<QuestItemReward*>();

    private:
        Regex *_regexMessage = new Regex("\"([^\"]*)\"");


    public:
        QuestInfo();

        QuestInfo(BinaryReader *reader);

        void Save(BinaryWriter *writer);

        void LoadInfo(bool clear = false);

        void ClearInfo();

        void ParseFile(std::vector<std::string> &lines);

        void ParseReward(std::vector<QuestItemReward*> &list, const std::string &line);

        QuestKillTask *ParseKill(const std::string &line);

        QuestItemTask *ParseItem(const std::string &line);

        QuestFlagTask *ParseFlag(const std::string &line);

        bool CanAccept(PlayerObject *player);

        ClientQuestInfo *CreateClientQuestInfo();

        static void FromText(const std::string &text);

        std::string ToText();

        std::string ToString();
    };

    class QuestKillTask
    {
    public:
        MonsterInfo *Monster;
        int Count = 0;
        std::string Message;
        virtual ~QuestKillTask()
        {
            delete Monster;
        }

    };

    class QuestItemTask
    {
    public:
        ItemInfo *Item;
        unsigned short Count = 0;
        std::string Message;
        virtual ~QuestItemTask()
        {
            delete Item;
        }

    };

    class QuestFlagTask
    {
    public:
        int Number = 0;
        std::string Message;
    };
}
